package cas.ihep.pwa.evtgen;

import java.io.Serializable;
import java.util.List;

public class EvtDecayBase implements Serializable{

    private EvtPDL pdl;

    public EvtDecayBase(EvtPDL pdl_){
        pdl=pdl_;
        defaultprobmax=1;
        ntimes_prob = 0;
        probmax = 0.0;
        _photos=0;
        _verbose=0;
        _summary=0;
        _parent=EvtId.defaultId;
        _ndaug=0;
        _narg=0;
        _daug=null;
        _args=null;
        _argsD=null;
        _modelname="**********";
        //Default is to check that charge is conserved
        _chkCharge=1;
        //statistics collection!
        max_prob=0.0;
        sum_prob=0.0;
    }

    public EvtDecayBase(String model,String cmd,EvtPDL pdl_){
        //the default is that the user module does _not_ set
        // any probmax.
        pdl=pdl_;
        defaultprobmax=1;
        ntimes_prob = 0;
        probmax = 0.0;
        _photos=0;
        _verbose=0;
        _summary=0;
        _parent=EvtId.defaultId;
        _ndaug=0;
        _narg=0;
        _daug=null;
        _args=null;
        _argsD=null;
        _modelname=model;
        _commandName=cmd;
        //Default is to check that charge is conserved
        _chkCharge=1;
        //statistics collection!
        max_prob=0.0;
        sum_prob=0.0;
    }

    private int _photos;
    private int _ndaug;
    private EvtId _parent;
    private int _narg;
    private EvtId _daug[];
    double _argsD[];
    String _args[];
    String _modelname,_commandName;
    double _brfr;
    int _dsum;
    int _summary;
    int _verbose;


    int defaultprobmax;
    double probmax;
    int ntimes_prob;

    //Should charge conservation be checked when model is
    //created? 1=yes 0 no.
    int _chkCharge;


    //These are used for gathering statistics.
    double sum_prob;
    double max_prob;

    // mode index in the decay list
    int _mode,_nFS;

    String getName(){
        return _modelname;
    }

    EvtId getParentId(){
        return _parent;
    }

    void init(){}

    void initProbMax(){
        defaultprobmax=1;
        ntimes_prob=0;
        probmax=0;
    }

    public int getNDaug(){
        return _ndaug;
    }

    public int getNArg(){
        return _narg;
    }

    public EvtId getDaug(int i){
        return _daug[i];
    }

    public double getBranchingFraction(){
        return _brfr;
    }

    void command(String cmd){}

    String commandName(){
        return _commandName;
    }

    void decay(){}

    void makeDecay(){}

    EvtDecayBase duplicate(){
        return new EvtDecayBase(_modelname,_commandName,pdl);
    }

    void saveDecayInfo(EvtId ipar, int ndaug,List<EvtId> daug,int narg,List<String> args,String name,double brfr){
        int i;
        _brfr=brfr;
        _ndaug=ndaug;
        _narg=narg;
        _parent=ipar;
        _dsum=0;
        if (_ndaug>0) {
            _daug=new EvtId [_ndaug];
            for(i=0;i<_ndaug;i++){
                _daug[i]=daug.get(i);
                _dsum+=daug.get(i).getAlias();
            }
        } else{
            _daug=null;
        }

        if (_narg>0) {
            _args=new String[_narg+1];
            for(i=0;i<_narg;i++){
                _args[i]=args.get(i);
            }
        } else{
            _args = null;
        }
        _modelname=name;
        init();
        initProbMax();

        if (_chkCharge!=0){
            checkQ();
        }

//        if (defaultprobmax){
//            report(INFO,"EvtGen") << "No default probmax for ";
//            report(INFO,"") << "("<<_modelname.c_str()<<") ";
//            report(INFO,"") << EvtPDL::name(_parent).c_str()<<" -> ";
//            for(i=0;i<_ndaug;i++){
//                report(INFO,"") << EvtPDL::name(_daug[i]).c_str() << " ";
//            }
//            report(INFO,"") << endl;
//            report(INFO,"") << "This is fine for development, but must be provided for production."<<endl;
//            report(INFO,"EvtGen") << "Never fear though - the decay will use the \n";
//            report(INFO,"EvtGen") << "500 iterations to build up a good probmax \n";
//            report(INFO,"EvtGen") << "before accepting a decay. "<<endl;
//        }
    }

    void checkQ(){
        int i;
        int q=0;
        int qpar;
        if ( _ndaug != 0) {
            for(i=0; i<_ndaug; i++ ) {
                q += pdl.chg3(_daug[i]);
            }
            qpar = pdl.chg3(_parent);
            if ( q != qpar ) {
                throw new RuntimeException();
            }
        }
    }
}
